var mongoose = require('mongoose'),
    sys = require('sys'),
    db = mongoose.connect('mongodb://localhost/p2p12'),
    Schema = mongoose.Schema,
    bcrypt = require('bcrypt'),
    SALT_WORK_FACTOR = 10;
 
UserSchema = new Schema({
    username: { type: String, required: true, index: { unique: true } },
    password: { type: String, required: true }
}),

UserSchema.pre('save', function(next) {
    var user = this;

    if (!user.isModified('password')) return next();

    bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
        if (err) return next(err);

        bcrypt.hash(user.password, salt, function(err, hash) {
            if (err) return next(err);

            user.password = hash;
            next();
        });
    });
}),

SuperNodeSchema = new Schema({
    address : String,
    port    : Number
}),

SuperNode = mongoose.model('SuperNode', SuperNodeSchema);

UserSchema.methods.comparePassword = function(candidatePassword, cb) {
    sys.puts("Sucess:" + candidatePassword);
    sys.puts("Sucess:" + this);
    sys.puts("Sucess:" + this.password);
    bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
        if (err) return cb(err);
        cb(null, isMatch);
    });
};

module.exports = 
{
    register: function(data, cb)
    {
        var User = mongoose.model('User', UserSchema);

        User.findOne({ username: data.username }, function(err, item)
        {
            if(err) throw err;

            if(item)
            {
                if(cb) cb(false);
                sys.puts("Failed.");
                return;
            }

            new User({
                username : data.username,
                password : data.password
            }).save(function()
            {
                if(cb) cb(true);

                sys.puts("Sucess.");
            });
        });       
    },

    login: function(data, cb)
    {
        var User = mongoose.model('User', UserSchema);

        User.findOne({ username: data.username }, function(err, item)
        {
            if(err) throw err;

            if(!item) 
            {
                sys.puts("Failed");

                if(cb) return cb(false);
            }
            else
                item.comparePassword(data.password, function(err, isMatch) {
                    if (err) throw err;
                 
                    sys.puts("Sucess:" + isMatch);

                    if(isMatch)
                    {

                        module.exports.selectPeers(cb);

                        module.exports.addSuperNode(data);
                    }
                    else
                        return cb(false);
                });
        });

    },

    selectPeers : function(cb)
    {
        var superNode = mongoose.model('SuperNode', SuperNodeSchema);

        return superNode.find({}, function(err, items)
        {
            if (!err){ 
               cb(items)
            }
            else { throw err;}

        })
    },

    addSuperNode : function(data)
    {
        //TODO: Uma boa regra aqui    
        if(true)
        {
            new SuperNode({
                address : data.address,
                port    : data.port
            }).save();
        }
    }
}